#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QDir>
#include <QDebug>
#include <QStandardItem>
#include <QHostAddress>
#include <QtNetwork>
#include <QKeyEvent>


static quint16 g_copyLocate[15];

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    QDir dir;
    if (!dir.exists("../EXC_SQL"))
        qDebug() << "目录../EXC_SQL不存在，尝试创建，是否成功" << dir.mkpath("../EXC_SQL");
    if (!dir.exists("../EXC_SQL/EXC_9200UDP_DEFINE.db"))
        qDebug() << "文件../EXC_SQL/EXC_9200UDP_DEFINE.db不存在，尝试创建，是否成功"
                 << QFile::copy(":/db/EXC_9200UDP_DEFINE_TEM.db", "../EXC_SQL/EXC_9200UDP_DEFINE.db");

    //建立和sqlite数据的连接
    db = QSqlDatabase::addDatabase("QSQLITE",QString("excmcrecorder"));
    db.setDatabaseName(QString("../EXC_SQL/EXC_9200UDP_DEFINE.db"));
    if(!db.open())return;

    //table
    QSqlQuery query(db);
    QString t_str = QString("SELECT ROWID,* from udp_define");
    query.exec(t_str);
    query.last();
    ui->tableWidget->setRowCount(query.at()+1);
    query.first();
    ui->tableWidget->setItem(0, 0, new QTableWidgetItem(query.value(2).toString()));
    while (query.next()) {
        ui->tableWidget->setItem(query.value(0).toUInt()-1, 0, new QTableWidgetItem(query.value(2).toString()));
    }

    //list
    t_str = QString("SELECT a.reg,a.bit,a.define,b.dec FROM \
                    (SELECT * FROM io_define WHERE define not like \"备用%\" AND define not like \"保留%\" ) a \
                    LEFT JOIN udp_define b\
                    WHERE a.reg = b.define");
    query.exec(t_str);
    while (query.next()) {
                        //A
        QListWidgetItem *t = new QListWidgetItem(query.value(2).toString());
        struct _IOBuf_ tio = {
            .dec = static_cast<quint16>(query.value(3).toUInt()),
                    .bit = static_cast<quint8>(query.value(1).toUInt()),
                    .point = t
        };
        m_ioVectorA.push_back(tio);
        ui->listIOA->addItem(t);
                        //B
        t = new QListWidgetItem(query.value(2).toString());
        struct _IOBuf_ tio2 = {
            .dec = static_cast<quint16>(query.value(3).toUInt()),
                    .bit = static_cast<quint8>(query.value(1).toUInt()),
                    .point = t
        };
        m_ioVectorB.push_back(tio2);
        ui->listIOB->addItem(t);
    }

    //udp
    m_udpSocketAll=new QUdpSocket();
    connect(m_udpSocketAll, &QUdpSocket::connected, this, [this](){
        ui->btnConnect->setText("disconnect");
    });
    connect(m_udpSocketAll, &QUdpSocket::readyRead, this, [this](){
        while (m_udpSocketAll->hasPendingDatagrams()) {
            QNetworkDatagram datagram = m_udpSocketAll->receiveDatagram();
            if(datagram.destinationAddress()==QHostAddress("239.1.1.215")){
                AnalyseDateA(datagram.data());
            }
            else if(datagram.destinationAddress()==QHostAddress("239.1.1.216")){
                AnalyseDateB(datagram.data());
            }
        }
    });

    //connect copy btn
    CopyBtnInit();

    //获取主机名
    QString localHostName = QHostInfo::localHostName();
    qDebug() << "localHostName" << localHostName;

    //获取本机的IP地址(可能有多条）
    QHostInfo info = QHostInfo::fromName(localHostName);
    qDebug()<<"IP Address："<< info.addresses();

    //只输出IPv4地址（可能有多条）
    foreach(QHostAddress address,info.addresses())
    {
        if(address.protocol() == QAbstractSocket::IPv4Protocol)
            ui->urlText_udpmy->addItem(address.toString());
    }
    ui->urlText_udpmy->addItem("0.0.0.0");
//    ui->urlText_udpmy->addItem("10.37.49.12");

    //copy locate
    query.exec("SELECT dec FROM udp_define WHERE define='ANALOG_UG'");
    query.next();
    g_copyLocate[0] = query.value(0).toUInt();
    query.exec("SELECT dec FROM udp_define WHERE define='ANALOG_UGA'");
    query.next();
    g_copyLocate[1] = query.value(0).toUInt();
    query.exec("SELECT dec FROM udp_define WHERE define='ANALOG_UGB'");
    query.next();
    g_copyLocate[2] = query.value(0).toUInt();
    query.exec("SELECT dec FROM udp_define WHERE define='ANALOG_UGC'");
    query.next();
    g_copyLocate[3] = query.value(0).toUInt();
    query.exec("SELECT dec FROM udp_define WHERE define='ANALOG_US'");
    query.next();
    g_copyLocate[4] = query.value(0).toUInt();
    query.exec("SELECT dec FROM udp_define WHERE define='ANALOG_IG'");
    query.next();
    g_copyLocate[5] = query.value(0).toUInt();
    query.exec("SELECT dec FROM udp_define WHERE define='ANALOG_IGA'");
    query.next();
    g_copyLocate[6] = query.value(0).toUInt();
    query.exec("SELECT dec FROM udp_define WHERE define='ANALOG_IGB'");
    query.next();
    g_copyLocate[7] = query.value(0).toUInt();
    query.exec("SELECT dec FROM udp_define WHERE define='ANALOG_IGC'");
    query.next();
    g_copyLocate[8] = query.value(0).toUInt();
    query.exec("SELECT dec FROM udp_define WHERE define='ANALOG_IL'");
    query.next();
    g_copyLocate[9] = query.value(0).toUInt();
    query.exec("SELECT dec FROM udp_define WHERE define='ANALOG_P'");
    query.next();
    g_copyLocate[10] = query.value(0).toUInt();
    query.exec("SELECT dec FROM udp_define WHERE define='ANALOG_Q'");
    query.next();
    g_copyLocate[11] = query.value(0).toUInt();
    query.exec("SELECT dec FROM udp_define WHERE define='ANALOG_UGD'");
    query.next();
    g_copyLocate[12] = query.value(0).toUInt();
    query.exec("SELECT dec FROM udp_define WHERE define='ANALOG_IGD'");
    query.next();
    g_copyLocate[13] = query.value(0).toUInt();
    query.exec("SELECT dec FROM udp_define WHERE define='ANALOG_UK'");
    query.next();
    g_copyLocate[14] = query.value(0).toUInt();

    qDebug() << "1";
    //
    m_cbReco1.push_back(ui->comboBox);
    query.exec("SELECT define,dec from udp_define WHERE bit=2");
    while (query.next()) {
        m_cbReco1[0]->addItem(query.value("define").toString());
        m_defReco.push_back(query.value("define").toString());
        m_decReco.push_back(query.value("dec").toUInt());
    }
    connect(ui->comboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
            this, [this](int index){
        ui->tw_reco1->setHorizontalHeaderItem(0, new QTableWidgetItem(m_cbReco1[0]->currentText()));
    });
    m_cbReco1.back()->setCurrentIndex(16);

    qDebug() << "2";
//    ui->tw_reco1->setDragDropMode()
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_btnConnect_clicked()
{
    if(ui->btnConnect->text().contains("disconnect")){
        m_udpSocketAll->disconnectFromHost();
        ui->btnConnect->setText("connect");
    }
    else
    {
        m_udpSocketAll->bind(QHostAddress(ui->urlText_udpmy->currentText()), 8898, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint);
//        m_udpSocketAll->bind(QHostAddress::AnyIPv4, 8898, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint);
        m_udpSocketAll->joinMulticastGroup(QHostAddress("239.1.1.215"));
        m_udpSocketAll->joinMulticastGroup(QHostAddress("239.1.1.216"));
        ui->btnConnect->setText("disconnect");
    }
}

void MainWindow::AnalyseDateA(QByteArray i_dat)
{
    m_bufACh = i_dat;
    quint8 binaryBuf[16]={0};
    QSqlQuery query(db);
    QString t_str = QString("SELECT ROWID,dec,bit,define from udp_define");
    query.exec(t_str);
    while (query.next()) {
        QString str;
        if(query.value(2).toUInt()==1)
        {
            str = QString::number((double)i_dat.at(query.value(1).toUInt()),'f',0);
        }
        else if(query.value(2).toUInt()==2)
        {
            if(query.value(3).toString().contains("BINARY"))
            {
                quint32 t = (quint8)i_dat.at(query.value(1).toUInt())<<8
                                    |(quint8)i_dat.at(query.value(1).toUInt()+1);
                str = QString::number(t, 16).toUpper();
//                binaryBuf[query.value(3).toString().mid(14).toUInt()] = query.value(1).toUInt();
            }
            else
            {
                quint32 t = (quint8)i_dat.at(query.value(1).toUInt())<<8
                                    |(quint8)i_dat.at(query.value(1).toUInt()+1);
                str = QString::number((double)t/100,'f',2);
            }
        }
        else if(query.value(2).toUInt()==4)
        {
            quint32 t = (quint8)i_dat.at(query.value(1).toUInt())<<8*3
                                |(quint8)i_dat.at(query.value(1).toUInt()+1)<<8*2
                                                                   |(quint8)i_dat.at(query.value(1).toUInt()+2)<<8*1
                                                                   |(quint8)i_dat.at(query.value(1).toUInt()+3);
            str = QString::number((double)t,'f',0);
        }
        ui->tableWidget->setItem(query.value(0).toUInt()-1, 1, new QTableWidgetItem(str));
    }

    for(int i=0; i<m_ioVectorA.size(); i++)
    {
        quint16 t = (quint8)i_dat.at(m_ioVectorA[i].dec)<<8
                            |(quint8)i_dat.at(m_ioVectorA[i].dec+1);
        m_ioVectorA[i].point->setCheckState(
                    (t & 1<<m_ioVectorA[i].bit)!=0?Qt::Checked:Qt::Unchecked);
    }

    for (int i=0; i<15; i++) {
        ui->tableWidget_2->setItem(i, 1, new QTableWidgetItem(
                                       QString::number(((double)(short)((i_dat.at(g_copyLocate[i])<<8)|(unsigned char)i_dat.at(g_copyLocate[i]+1))/100),'f',2)+"\t"
                                       ));
    }
}

void MainWindow::AnalyseDateB(QByteArray i_dat)
{
    m_bufBCh = i_dat;
    QSqlQuery query(db);
    QString t_str = QString("SELECT ROWID,dec,bit,define from udp_define");
    query.exec(t_str);
    while (query.next()) {
        QString str;
        if(query.value(2).toUInt()==1)
        {
            str = QString::number((double)i_dat.at(query.value(1).toUInt()),'f',0);
        }
        else if(query.value(2).toUInt()==2)
        {
            if(query.value(3).toString().contains("BINARY"))
            {
                quint32 t = (quint8)i_dat.at(query.value(1).toUInt())<<8
                                    |(quint8)i_dat.at(query.value(1).toUInt()+1);
                str = QString::number(t, 16).toUpper();
            }
            else
            {
                quint32 t = (quint8)i_dat.at(query.value(1).toUInt())<<8
                                             |(quint8)i_dat.at(query.value(1).toUInt()+1);
                str = QString::number((double)t/100,'f',2);
            }
        }
        else if(query.value(2).toUInt()==4)
        {
            quint32 t = (quint8)i_dat.at(query.value(1).toUInt())<<8*3
                                |(quint8)i_dat.at(query.value(1).toUInt()+1)<<8*2
                                                                   |(quint8)i_dat.at(query.value(1).toUInt()+2)<<8*1
                                                                   |(quint8)i_dat.at(query.value(1).toUInt()+3);
            str = QString::number((double)t,'f',0);
        }
        ui->tableWidget->setItem(query.value(0).toUInt()-1, 2, new QTableWidgetItem(str));

        for(int i=0; i<m_ioVectorB.size(); i++)
        {
            quint16 t = (quint8)i_dat.at(m_ioVectorB[i].dec)<<8
                                |(quint8)i_dat.at(m_ioVectorB[i].dec+1);
            m_ioVectorB[i].point->setCheckState(
                        (t & 1<<m_ioVectorB[i].bit)!=0?Qt::Checked:Qt::Unchecked);
        }
    }

    for(int i=0; i<m_ioVectorB.size(); i++)
    {
        quint16 t = (quint8)i_dat.at(m_ioVectorB[i].dec)<<8
                            |(quint8)i_dat.at(m_ioVectorB[i].dec+1);
        m_ioVectorB[i].point->setCheckState(
                    (t & 1<<m_ioVectorB[i].bit)!=0?Qt::Checked:Qt::Unchecked);
    }

    for (int i=0; i<15; i++) {
        ui->tableWidget_2->setItem(i, 2, new QTableWidgetItem(
                                       QString::number(((double)(short)((i_dat.at(g_copyLocate[i])<<8)|(unsigned char)i_dat.at(g_copyLocate[i]+1))/100),'f',2)+"\t"
                                       ));
    }
}

#include <QClipboard>
void MainWindow::CopyBtnInit()
{
    connect(ui->btn_ugA, &QPushButton::clicked, this, [this](){
        QClipboard *clipboard = QApplication::clipboard();
        clipboard->setText(
                    QString::number(((double)((short)(m_bufACh.at(g_copyLocate[0])<<8)|(unsigned char)m_bufACh.at(g_copyLocate[0]+1))/100),'f',2)+"\t"+
                QString::number(((double)(short)((m_bufACh.at(g_copyLocate[1])<<8)|(unsigned char)m_bufACh.at(g_copyLocate[1]+1))/100),'f',2)+"\t"+
                QString::number(((double)(short)((m_bufACh.at(g_copyLocate[2])<<8)|(unsigned char)m_bufACh.at(g_copyLocate[2]+1))/100),'f',2)+"\t"+
                QString::number(((double)(short)((m_bufACh.at(g_copyLocate[3])<<8)|(unsigned char)m_bufACh.at(g_copyLocate[3]+1))/100),'f',2)+"\t"+
                QString::number(((double)(short)((m_bufACh.at(g_copyLocate[4])<<8)|(unsigned char)m_bufACh.at(g_copyLocate[4]+1))/100),'f',2)
                );
    });
    connect(ui->btn_igA, &QPushButton::clicked, this, [this](){
        QClipboard *clipboard = QApplication::clipboard();
        clipboard->setText(
                    QString::number(((double)(short)((m_bufACh.at(g_copyLocate[5])<<8)|(unsigned char)m_bufACh.at(g_copyLocate[5]+1))/100),'f',2)+"\t"+
                QString::number(((double)(short)((m_bufACh.at(g_copyLocate[6])<<8)|(unsigned char)m_bufACh.at(g_copyLocate[6]+1))/100),'f',2)+"\t"+
                QString::number(((double)(short)((m_bufACh.at(g_copyLocate[7])<<8)|(unsigned char)m_bufACh.at(g_copyLocate[7]+1))/100),'f',2)+"\t"+
                QString::number(((double)(short)((m_bufACh.at(g_copyLocate[8])<<8)|(unsigned char)m_bufACh.at(g_copyLocate[8]+1))/100),'f',2)
                );
    });
    connect(ui->btn_iLA, &QPushButton::clicked, this, [this](){
        QClipboard *clipboard = QApplication::clipboard();
        clipboard->setText(
                    QString::number(((double)(short)((m_bufACh.at(g_copyLocate[9])<<8)|(unsigned char)m_bufACh.at(g_copyLocate[9]+1))/100),'f',2)
                    );
    });
    connect(ui->btn_ugB, &QPushButton::clicked, this, [this](){
        QClipboard *clipboard = QApplication::clipboard();
        clipboard->setText(
                    QString::number(((double)(short)((m_bufBCh.at(g_copyLocate[0])<<8)|(unsigned char)m_bufBCh.at(g_copyLocate[0]+1))/100),'f',2)+"\t"+
                QString::number(((double)(short)((m_bufBCh.at(g_copyLocate[1])<<8)|(unsigned char)m_bufBCh.at(g_copyLocate[1]+1))/100),'f',2)+"\t"+
                QString::number(((double)(short)((m_bufBCh.at(g_copyLocate[2])<<8)|(unsigned char)m_bufBCh.at(g_copyLocate[2]+1))/100),'f',2)+"\t"+
                QString::number(((double)(short)((m_bufBCh.at(g_copyLocate[3])<<8)|(unsigned char)m_bufBCh.at(g_copyLocate[3]+1))/100),'f',2)+"\t"+
                QString::number(((double)(short)((m_bufBCh.at(g_copyLocate[4])<<8)|(unsigned char)m_bufBCh.at(g_copyLocate[4]+1))/100),'f',2)
                );
    });
    connect(ui->btn_igB, &QPushButton::clicked, this, [this](){
        QClipboard *clipboard = QApplication::clipboard();
        clipboard->setText(
                    QString::number(((double)(short)((m_bufBCh.at(g_copyLocate[5])<<8)|(unsigned char)m_bufBCh.at(g_copyLocate[5]+1))/100),'f',2)+"\t"+
                QString::number(((double)(short)((m_bufBCh.at(g_copyLocate[6])<<8)|(unsigned char)m_bufBCh.at(g_copyLocate[6]+1))/100),'f',2)+"\t"+
                QString::number(((double)(short)((m_bufBCh.at(g_copyLocate[7])<<8)|(unsigned char)m_bufBCh.at(g_copyLocate[7]+1))/100),'f',2)+"\t"+
                QString::number(((double)(short)((m_bufBCh.at(g_copyLocate[8])<<8)|(unsigned char)m_bufBCh.at(g_copyLocate[8]+1))/100),'f',2)
                );
    });
    connect(ui->btn_iLB, &QPushButton::clicked, this, [this](){
        QClipboard *clipboard = QApplication::clipboard();
        clipboard->setText(
                    QString::number(((double)(short)((m_bufBCh.at(g_copyLocate[9])<<8)|(unsigned char)m_bufBCh.at(g_copyLocate[9]+1))/100),'f',2)
                    );
    });
    connect(ui->btn_pqAB, &QPushButton::clicked, this, [this](){
        QClipboard *clipboard = QApplication::clipboard();
        clipboard->setText(
                    QString::number(((double)(short)((m_bufACh.at(g_copyLocate[10])<<8)|(unsigned char)m_bufACh.at(g_copyLocate[10]+1))/100),'f',2)+"\t"+
                QString::number(((double)(short)((m_bufACh.at(g_copyLocate[11])<<8)|(unsigned char)m_bufACh.at(g_copyLocate[11]+1))/100),'f',2)+"\t"+
                QString::number(((double)(short)((m_bufBCh.at(g_copyLocate[10])<<8)|(unsigned char)m_bufBCh.at(g_copyLocate[10]+1))/100),'f',2)+"\t"+
                QString::number(((double)(short)((m_bufBCh.at(g_copyLocate[11])<<8)|(unsigned char)m_bufBCh.at(g_copyLocate[11]+1))/100),'f',2)
                );
    });
}

void MainWindow::on_pushButton_clicked()
{
    QWidget *t = new QWidget;
//    QG
    ui->tabWidget->addTab(t, "校准表格1");
}


void MainWindow::on_btn_reco1addlist_clicked()
{
    //增加table行数
    int colnum = ui->tw_reco1->columnCount();
    ui->tw_reco1->setColumnCount(colnum+1);
    //向vector句柄增加下拉菜单对象
    QComboBox* t = new QComboBox;
    foreach(QString s, m_defReco)
    {
        t->addItem(s);
    }
    m_cbReco1.push_back(t);
    //绑定
    int i = m_cbReco1.size()-1;
    connect(t, QOverload<int>::of(&QComboBox::currentIndexChanged),
            this, [this, i](int index){
        ui->tw_reco1->setHorizontalHeaderItem(i, new QTableWidgetItem(m_cbReco1[i]->currentText()));
    });
    m_cbReco1.back()->setCurrentIndex(17);
    //加入UI
    ui->verticalLayout->addWidget(m_cbReco1.back());
}

void MainWindow::on_btn_reco1declist_clicked()
{
    int colnum = ui->tw_reco1->columnCount();
    if(colnum<=1) return;
    //从UI移除下拉菜单
    ui->verticalLayout->removeWidget(m_cbReco1.back());
    //从UI移除table列
    ui->tw_reco1->setColumnCount(colnum-1);
    //从vector句柄移除下拉菜单对象并删除
    m_cbReco1.back()->deleteLater();
    m_cbReco1.pop_back();
}

void MainWindow::on_btn_reco1addnote_clicked()
{
    int rownum = ui->tw_reco1->rowCount();
    ui->tw_reco1->setRowCount(rownum+1);
    for(int i=0; i<m_cbReco1.size(); i++)
    {
        //SQL定义的位置
        int j = m_cbReco1.at(i)->currentIndex();
        //根据SQL定义的位置，找到对应位置的dec，再找到mem缓冲的数据
        QString s = QString::number(((double)((short)(m_bufACh.at(m_decReco.at(j))<<8)
                         |(unsigned char)m_bufACh.at(m_decReco.at(j)+1))/100),'f',2);
        ui->tw_reco1->setItem(rownum, i, new QTableWidgetItem(s));
    }
}

void MainWindow::on_btn_reco1decnote_clicked()
{
    ui->tw_reco1->removeRow(ui->tw_reco1->currentRow());
}

void MainWindow::on_pushButton_2_clicked()
{
    QString copied_text;
    QList<QTableWidgetItem *> current_selected_indexs = ui->tw_reco1->selectedItems();
    int current_row = current_selected_indexs.at(0)->row();
    for(int i = 0; i < current_selected_indexs.count(); i++){
        if(current_row != current_selected_indexs.at(i)->row()){
            current_row = current_selected_indexs.at(i)->row();
            copied_text.append("\n");
            copied_text.append(current_selected_indexs.at(i)->text());
            continue;
        }
        if(0 != i){
            copied_text.append("\t");
        }
        copied_text.append(current_selected_indexs.at(i)->text());
    }
    copied_text.append("\n");
    QApplication::clipboard()->setText(copied_text);
}
